package org.example4;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

//advice通知类增强类
@Component("myAspect")//<bean id="myAspectAdvice"/>
@Aspect//<aop:aspect ref="myAspectAdvice">
public class MyAspect {

    //自定义切入点
    //方法名就是切入点的名字
    //<aop:pointcut expression="bean(*Service)" id="myPointcut()"/>
    @Pointcut("bean(*Service)")
    private void myPointcut() {
    }

    @Pointcut("bean(*Service)")
    private void myPointcut2() {
    }

    //前置通知
    //<aop:before method="before" pointcut-ref="myPointcut" />
    //<aop:after method="before" pointcut="bean(*Service)"/>
//	@Before("bean(*Service)")//参数值：自动支持切入点表达式或切入点名字
    @Before("myPointcut()||myPointcut2()||bean(*Service)")
    public void before(JoinPoint joinPoint) {
        System.out.println("------MyAspect类前置通知------");
    }

    //后置通知
    //target：拦截某一个类型的bean
//	@AfterReturning(value="target(cn.itcast.spring.a_aspectj.CustomerServiceImpl)",returning="returnVal")
    public void afterReturning(JoinPoint joinPoint, Object returnVal) {
        System.out.println("----MyAspect类afterReturning后置通知-----");
    }

    //环绕通知：
	@Around("execution(* org.example4..*.*(..))")//要增强所有的service类型的所有方法
//	@Around("execution(* cn.itcast.spring..*.*(..))")//要增强任意的返回值类型，指定的包及其子包下面的所有类的所有方法，任意参数
//	@Around("execution(* cn.itcast..*.save(..))")//增强任意包下面的任意类型下面的save方法
    //要增强某个类型的子类型的所有方法
//	@Around("execution(* cn.itcast.spring.a_aspectj.CustomerService+.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("---MyAspect类around环绕通知-----前");
        Object object = proceedingJoinPoint.proceed();
        System.out.println("---MyAspect类around环绕通知-----后");
        return object;
    }

    //抛出通知
    //切入点表达式：增强所有cn包以及子包下面的所有类型的bean的所有方法
//	@AfterThrowing(value="within(cn..*)",throwing="ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
        System.out.println("-----MyAspect类afterThrowing抛出通知------");
    }

    //最终通知
    //拦截所有以ice结尾的bean
//	@After("bean(*ice)")
    public void after(JoinPoint joinPoint) {
        System.out.println("-------MyAspect类after最终通知-------");
    }
}
